﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Structure;
using Autodesk.Revit.UI;
using YArchitech.Revit;
using YJKRevitStairs.StairsModel.CommonUnit;
using YJKRevitStairs.StairsModel.DataInfos;
using YJKRevitStairs.StairsModel.Kit;

namespace YJKRevitStairs.StairsModel.Manage
{
	public class EscalatorCreator : StairsCreator
	{
		public EscalatorCreator(ExternalCommandData commandData) : base(commandData)
		{
		}

		public Family LoadFamily(Autodesk.Revit.DB.Document doc, string familyFileName, string symbolName)
		{
			string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(familyFileName);
			Family family = null;
			Transaction transaction = new Transaction(doc, "LoadFamily");
			try
			{
				if (family == null)
				{
					transaction.Start();
					FamilyLoadUtils.LoadFamily(doc, familyFileName, fileNameWithoutExtension, symbolName, out family);
					transaction.Commit();
				}
			}
			catch (Exception)
			{
                if ((int)transaction.GetStatus() == 1)
				{
					transaction.RollBack();
				}
			}
			return family;
		}

		public FamilySymbol FindFamilySymbol(Family family, string symbolName)
		{
			FamilySymbol result = null;
			if (family != null)
			{
				foreach (FamilySymbol familySymbol in family.GetSymbols())
				{
					if (familySymbol.Name == symbolName)
					{
						result = familySymbol;
						break;
					}
				}
			}
			return result;
		}

		public FamilyInstance CreateFamilyInstance(Autodesk.Revit.DB.Document doc, XYZ ptInsert, FamilySymbol symbol, StructuralType StructuralType)
		{
			FamilyInstance result = null;
			Transaction transaction = new Transaction(doc, "create famIns");
			transaction.Start();
			try
			{
				if (!symbol.IsActive)
				{
					symbol.Activate();
				}
				Level genLevel = this.m_Document.ActiveView.GenLevel;
				result = doc.Create.NewFamilyInstance(ptInsert, symbol, genLevel, StructuralType);
				transaction.Commit();
			}
			catch (Exception)
			{
				transaction.RollBack();
			}
			return result;
		}

		public void RotateFamilyInstance(FamilyInstance famIns, XYZ ptCenter, double dAngle)
		{
			Transaction transaction = new Transaction(this.m_Document, "rotate instance");
			transaction.Start();
			try
			{
				ElementTransformUtils.RotateElement(this.m_Document, famIns.Id, Line.CreateBound(ptCenter, new XYZ(ptCenter.X, ptCenter.Y, ptCenter.Z + 10.0)), dAngle);
				transaction.Commit();
			}
			catch (Exception)
			{
				transaction.RollBack();
			}
		}

		public void TurnInstance(FamilyInstance famIns, double dRotateAngle)
		{
			Transaction transaction = new Transaction(this.m_Document, "Trans");
			transaction.Start();
			try
			{
				double dHori = 0.0;
				double dVert = 0.0;
				this.GetFamilyWidthAndLength(famIns, out dHori, out dVert);
				XYZ instanceInsertPoint = this.GetInstanceInsertPoint(famIns);
				XYZ xyz = this.GetCenterPoint(dHori, dVert, instanceInsertPoint) - instanceInsertPoint;
				xyz = Geometry.RotateTo(xyz, dRotateAngle, XYZ.BasisZ);
				XYZ xyz2 = instanceInsertPoint + xyz;
				ElementTransformUtils.RotateElement(this.m_Document, famIns.Id, Line.CreateBound(xyz2, new XYZ(xyz2.X, xyz2.Y, xyz2.Z + 10.0)), Math.PI);
				transaction.Commit();
			}
			catch (Exception)
			{
				transaction.RollBack();
			}
		}

		public XYZ GetCenterPoint(double dHori, double dVert, XYZ ptOrigin)
		{
			XYZ zero = XYZ.Zero;
			XYZ xyz = new XYZ(0.0, dVert, 0.0);
			XYZ xyz2 = new XYZ(dHori, 0.0, 0.0);
			XYZ ptEnd = ptOrigin + xyz;
			XYZ ptEnd2 = ptOrigin + xyz2;
			XYZ xyz3 = Geometry.CalculatMidPoint(ptOrigin, ptEnd);
			return new XYZ(Geometry.CalculatMidPoint(ptOrigin, ptEnd2).X, xyz3.Y, 0.0);
		}

		public void GetFamilyWidthAndLength(FamilyInstance famIns, out double dHori, out double dVert)
		{
			dVert = 0.0;
			dHori = 0.0;
			Parameter parameter = famIns.GetParameter("水平跨度");
			if (parameter != null)
			{
				dVert = parameter.AsDouble();
			}
			parameter = famIns.GetParameter("地坑最小宽度");
			if (parameter != null)
			{
				dHori = parameter.AsDouble();
				return;
			}
			parameter = famIns.GetParameter("下部梯坑宽度");
			if (parameter != null)
			{
				dHori = parameter.AsDouble();
			}
		}

		public void TranslationInstanceToPreview(FamilyInstance famIns, Escalator.PosInsertType insertType)
		{
			Transaction transaction = new Transaction(this.m_Document, "trans Preview");
			transaction.Start();
			try
			{
				double dHori = 0.0;
				double dVert = 0.0;
				this.GetFamilyWidthAndLength(famIns, out dHori, out dVert);
				XYZ instanceSelfTransVector = this.GetInstanceSelfTransVector(insertType, dHori, dVert);
				if (!instanceSelfTransVector.Equals(XYZ.Zero))
				{
					ElementTransformUtils.MoveElement(this.m_Document, famIns.Id, instanceSelfTransVector);
				}
				transaction.Commit();
			}
			catch (Exception)
			{
				transaction.RollBack();
			}
		}

		public FamilyInstance ChangeInstanceParamValues(Escalator param_stairs, FamilyInstance famIns)
		{
			FamilyInstance result = famIns;
			Transaction transaction = new Transaction(this.m_Document, "change Param");
			transaction.Start();
			try
			{
				double dStairsHigh = param_stairs.m_dStairsHigh;
				this.SetInstanceDoubleParamValue(famIns, "提升高度", dStairsHigh);
				double dStairsOffset = param_stairs.m_dStairsOffset;
				this.SetInstanceDoubleParamValue(famIns, dStairsOffset);
				double dRunWidth = param_stairs.m_dRunWidth;
				this.SetInstanceDoubleParamValue(famIns, "梯级宽度", dRunWidth);
				this.SetInstanceDoubleParamValue(famIns, "人行道宽度", dRunWidth);
				this.SetInstanceDoubleParamValue(famIns, "自动人行道宽度", dRunWidth);
				if (param_stairs.m_bAsRamp && param_stairs.m_dInclienAngle == 0.0)
				{
					double dValue = param_stairs.m_dRunLength + param_stairs.m_dStartDepth + param_stairs.m_dTreadDepth * 2.0 + param_stairs.m_dFrontDepth;
					this.SetInstanceDoubleParamValue(famIns, "水平跨度", dValue);
				}
				else
				{
					double dHSpan = param_stairs.m_dHSpan;
					this.SetInstanceDoubleParamValue(famIns, "水平跨度", dHSpan);
				}
				double dRunDepth = param_stairs.m_dRunDepth;
				this.SetInstanceDoubleParamValue(famIns, "梯级深度", dRunDepth);
				double dFrontDepth = param_stairs.m_dFrontDepth;
				this.SetInstanceDoubleParamValue(famIns, "前沿进深", dFrontDepth);
				double dStartDepth = param_stairs.m_dStartDepth;
				this.SetInstanceDoubleParamValue(famIns, "起步进深", dStartDepth);
				double dTreadDepth = param_stairs.m_dTreadDepth;
				this.SetInstanceDoubleParamValue(famIns, "踏板进深", dTreadDepth);
				double dInclienAngle = param_stairs.m_dInclienAngle;
				this.SetInstanceDoubleParamValue(famIns, "倾斜角度", dInclienAngle);
				double dRailHeight = param_stairs.m_dRailHeight;
				this.SetInstanceDoubleParamValue(famIns, "栏杆高度", dRailHeight);
				dRailHeight = param_stairs.m_dRailHeight;
				this.SetInstanceDoubleParamValue(famIns, "扶手高度", dRailHeight);
				TransactionStatus transactionStatus = transaction.Commit();
                if (2 == (int)transactionStatus)
				{
					result = null;
				}
			}
			catch (Exception)
			{
				transaction.RollBack();
			}
			return result;
		}

		private void SetDefaultArrowVisible(FamilyInstance famIns)
		{
			try
			{
				this.SetInstanceIntParam(famIns, "首层箭头上", false);
				this.SetInstanceIntParam(famIns, "首层箭头下", false);
				this.SetInstanceIntParam(famIns, "首层线可见性", false);
				this.SetInstanceIntParam(famIns, "顶部注释文字可见性", false);
				this.SetInstanceIntParam(famIns, "顶层箭头下", false);
				this.SetInstanceIntParam(famIns, "顶层箭头上", false);
				this.SetInstanceIntParam(famIns, "顶层线可见性", false);
				this.SetInstanceIntParam(famIns, "底部注释文字可见性", false);
				this.SetInstanceIntParam(famIns, "中层箭头下下", false);
				this.SetInstanceIntParam(famIns, "中层箭头下上", false);
				this.SetInstanceIntParam(famIns, "中层箭头上下", false);
				this.SetInstanceIntParam(famIns, "中层箭头上上", false);
				this.SetInstanceIntParam(famIns, "中层下部线可见性", false);
				this.SetInstanceIntParam(famIns, "中层上部线可见性", false);
				this.SetInstanceIntParam(famIns, "图例注释文字可见性", false);
				this.SetInstanceIntParam(famIns, "图例线可见性", true);
				this.SetInstanceIntParam(famIns, "图例箭头下", false);
				this.SetInstanceIntParam(famIns, "图例箭头上", false);
			}
			catch (Exception)
			{
			}
		}

		public FamilyInstance CreateOriginInstance(Autodesk.Revit.DB.Document doc, string sFamFullPath, string sSymbolName, XYZ ptInsert)
		{
			Family family = this.LoadFamily(this.m_Document, sFamFullPath, sSymbolName);
			FamilySymbol familySymbol = this.FindFamilySymbol(family, sSymbolName);
			if (familySymbol == null)
			{
				return null;
			}
			return this.CreateFamilyInstance(this.m_Document, ptInsert, familySymbol, 0);
		}

		public FamilyInstance CreateOneInstance(Autodesk.Revit.DB.Document doc, string sFamFullPath, string sSymbolName, Escalator param_stairs, XYZ ptInsert)
		{
			Escalator.PosInsertType posInsertType = param_stairs.m_PosInsertType;
            YJKRevitStairs.StairsModel.DataInfos.FloorType floorType = param_stairs.m_FloorType;
			bool bNoteUpStairs = param_stairs.m_bNoteUpStairs;
			UpStairsType upStairsType = param_stairs.m_UpStairsType;
			FamilyInstance familyInstance = null;
			double dRotateAngle = param_stairs.m_dRotateAngle;
			FamilyInstance familyInstance2 = this.CreateOriginInstance(doc, sFamFullPath, sSymbolName, ptInsert);
			if (familyInstance2 == null)
			{
				return null;
			}
			familyInstance = this.ChangeInstanceParamValues(param_stairs, familyInstance2);
			if (familyInstance == null)
			{
				Transaction transaction = new Transaction(this.m_Document, "delParmIns");
				transaction.Start();
				try
				{
					this.m_Document.Delete(familyInstance2.Id);
					transaction.Commit();
				}
				catch (Exception)
				{
					transaction.RollBack();
				}
				return null;
			}
			this.TranslationInstanceToPreview(familyInstance, posInsertType);
			this.RotateFamilyInstance(familyInstance, ptInsert, dRotateAngle);
			Transaction transaction2 = new Transaction(doc, "set visible");
			transaction2.Start();
			try
			{
				this.SetDefaultArrowVisible(familyInstance);
				this.SetInstanceFloorType(floorType, familyInstance);
				transaction2.Commit();
			}
			catch (Exception)
			{
				transaction2.RollBack();
			}
			return familyInstance;
		}

		public FamilyInstance CreateOnePitAtPoint(Autodesk.Revit.DB.Document doc, string sFamFullPath, string sSymbolName, double dLength, double dWidth, double dHeight, XYZ ptInsert, double dAngle, double dOffset = 0.0)
		{
			FamilyInstance familyInstance = this.CreateOriginInstance(doc, sFamFullPath, sSymbolName, ptInsert);
			this.RotateFamilyInstance(familyInstance, ptInsert, dAngle);
			if (familyInstance != null)
			{
				Transaction transaction = new Transaction(doc, "change Pit param");
				transaction.Start();
				try
				{
					this.SetInstanceDoubleParamValue(familyInstance, "梯坑长度", dLength);
					this.SetInstanceDoubleParamValue(familyInstance, "梯坑宽度", dWidth);
					this.SetInstanceDoubleParamValue(familyInstance, "梯坑深度", dHeight);
					this.SetInstanceDoubleParamValue(familyInstance, dOffset);
					transaction.Commit();
				}
				catch
				{
					transaction.RollBack();
				}
			}
			return familyInstance;
		}

		public XYZ GetInstanceSelfTransVector(Escalator.PosInsertType InsertType, double dHori, double dVert)
		{
			XYZ result = XYZ.Zero;
			switch (InsertType)
			{
			case Escalator.PosInsertType.PIT_LftBtm:
				result = XYZ.Zero;
				break;
			case Escalator.PosInsertType.PIT_LftTop:
				result = -XYZ.BasisY * dVert;
				break;
			case Escalator.PosInsertType.PIT_RhtBtm:
				result = -XYZ.BasisX * dHori;
				break;
			case Escalator.PosInsertType.PIT_RhtTop:
				result = -(XYZ.BasisX * dHori + XYZ.BasisY * dVert);
				break;
			}
			return result;
		}

		public XYZ GetPlaceInstanceVector(Escalator.PosInsertType InsertType)
		{
			XYZ result = XYZ.BasisX;
			switch (InsertType)
			{
			case Escalator.PosInsertType.PIT_LftBtm:
				result = XYZ.BasisX;
				break;
			case Escalator.PosInsertType.PIT_LftTop:
				result = XYZ.BasisX;
				break;
			case Escalator.PosInsertType.PIT_RhtBtm:
				result = -XYZ.BasisX;
				break;
			case Escalator.PosInsertType.PIT_RhtTop:
				result = -XYZ.BasisX;
				break;
			}
			return result;
		}

		public XYZ GetCopyInstanceTransVector(Escalator.PosInsertType InsertType, FamilyInstance famIns, double dDis, double dRotateAngle)
		{
			XYZ placeInstanceVector = this.GetPlaceInstanceVector(InsertType);
			double num = 0.0;
			double num2 = 0.0;
			this.GetFamilyWidthAndLength(famIns, out num, out num2);
			XYZ xyz = Geometry.RotateTo(placeInstanceVector, dRotateAngle, XYZ.BasisZ);
			double num3 = num + dDis;
			return xyz.Multiply(num3);
		}

		private List<FamilyInstance> CopyEsclatorByVector(FamilyInstance famSource, XYZ vecTrans, int nRunCount)
		{
			List<FamilyInstance> list = new List<FamilyInstance>();
			list.Add(famSource);
			Transaction transaction = new Transaction(this.m_Document, "copy");
			transaction.Start();
			try
			{
				for (int i = 0; i < nRunCount; i++)
				{
					double num = (double)(i + 1);
					XYZ xyz = vecTrans.Multiply(num);
					ICollection<ElementId> collection = ElementTransformUtils.CopyElement(this.m_Document, famSource.Id, xyz);
					if (collection.Count > 0)
					{
						ElementId elementId = collection.First<ElementId>();
						FamilyInstance familyInstance = this.m_Document.GetElement(elementId) as FamilyInstance;
						if (familyInstance != null)
						{
							list.Add(familyInstance);
						}
					}
				}
				transaction.Commit();
			}
			catch (Exception)
			{
				transaction.RollBack();
			}
			return list;
		}

		public XYZ GetInstanceInsertPoint(FamilyInstance famIns)
		{
			XYZ result = XYZ.Zero;
			LocationPoint locationPoint = famIns.Location as LocationPoint;
			if (locationPoint != null)
			{
				result = locationPoint.Point;
			}
			return result;
		}

        private void SetInstanceFloorType(YJKRevitStairs.StairsModel.DataInfos.FloorType fType, FamilyInstance famIns)
		{
			try
			{
				switch (fType)
				{
                case YJKRevitStairs.StairsModel.DataInfos.FloorType.FT_Bottom:
					this.SetInstanceIntParam(famIns, "首层图例", true);
					this.SetInstanceIntParam(famIns, "中间层图例", false);
					this.SetInstanceIntParam(famIns, "顶层图例", false);
					break;
                case YJKRevitStairs.StairsModel.DataInfos.FloorType.FT_Mid:
					this.SetInstanceIntParam(famIns, "首层图例", false);
					this.SetInstanceIntParam(famIns, "中间层图例", true);
					this.SetInstanceIntParam(famIns, "顶层图例", false);
					break;
                case YJKRevitStairs.StairsModel.DataInfos.FloorType.FT_Top:
					this.SetInstanceIntParam(famIns, "首层图例", false);
					this.SetInstanceIntParam(famIns, "中间层图例", false);
					this.SetInstanceIntParam(famIns, "顶层图例", true);
					break;
				}
				this.SetInstanceIntParam(famIns, "图例", true);
			}
			catch (Exception)
			{
			}
		}

		private List<Escalator.DrawPitData> GetDrawPitData(List<Escalator.Direction> arDirecion)
		{
			int count = arDirecion.Count;
			List<Escalator.DrawPitData> list = new List<Escalator.DrawPitData>();
			switch (count)
			{
			case 1:
			{
				Escalator.DrawPitData item = new Escalator.DrawPitData(0, arDirecion[0]);
				list.Add(item);
				break;
			}
			case 2:
			{
				Escalator.Direction direction = arDirecion[0];
				Escalator.Direction direction2 = arDirecion[1];
				if (direction.m_bIsReverse == direction2.m_bIsReverse)
				{
					Escalator.DrawPitData item2 = new Escalator.DrawPitData(1, direction);
					list.Add(item2);
				}
				else
				{
					Escalator.DrawPitData item3 = new Escalator.DrawPitData(0, direction);
					list.Add(item3);
					item3 = new Escalator.DrawPitData(0, direction2);
					list.Add(item3);
				}
				break;
			}
			case 3:
			{
				Escalator.Direction direction3 = arDirecion[0];
				Escalator.Direction direction4 = arDirecion[1];
				Escalator.Direction direction5 = arDirecion[2];
				if (direction3.m_bIsReverse == direction4.m_bIsReverse && direction4.m_bIsReverse == direction5.m_bIsReverse)
				{
					Escalator.DrawPitData item4 = new Escalator.DrawPitData(2, direction3);
					list.Add(item4);
				}
				else
				{
					Escalator.DrawPitData item5 = new Escalator.DrawPitData(0, direction3);
					list.Add(item5);
					item5 = new Escalator.DrawPitData(0, direction4);
					list.Add(item5);
					item5 = new Escalator.DrawPitData(0, direction5);
					list.Add(item5);
				}
				break;
			}
			case 4:
			{
				Escalator.Direction direction6 = arDirecion[0];
				Escalator.Direction direction7 = arDirecion[1];
				Escalator.Direction direction8 = arDirecion[2];
				Escalator.Direction direction9 = arDirecion[3];
				if (direction6.m_bIsReverse == direction7.m_bIsReverse && direction7.m_bIsReverse == direction8.m_bIsReverse && direction8.m_bIsReverse == direction9.m_bIsReverse)
				{
					Escalator.DrawPitData item6 = new Escalator.DrawPitData(3, direction6);
					list.Add(item6);
				}
				else if (direction7.m_bIsReverse == direction8.m_bIsReverse)
				{
					Escalator.DrawPitData item7 = new Escalator.DrawPitData(0, direction6);
					list.Add(item7);
					item7 = new Escalator.DrawPitData(1, direction7);
					list.Add(item7);
					item7 = new Escalator.DrawPitData(0, direction9);
					list.Add(item7);
				}
				else
				{
					Escalator.DrawPitData item8 = new Escalator.DrawPitData(0, direction6);
					list.Add(item8);
					item8 = new Escalator.DrawPitData(0, direction7);
					list.Add(item8);
					item8 = new Escalator.DrawPitData(0, direction8);
					list.Add(item8);
					item8 = new Escalator.DrawPitData(0, direction9);
					list.Add(item8);
				}
				break;
			}
			}
			return list;
		}

		private XYZ GetBtmPitPtInsert(FamilyInstance fIns, double dLength, double dHori, double dAngle, bool bIsTurn)
		{
			XYZ xyz = this.GetInstanceInsertPoint(fIns);
			XYZ xyz2 = XYZ.BasisY;
			XYZ xyz3 = XYZ.BasisX;
			if (bIsTurn)
			{
				xyz2 = Geometry.RotateTo(xyz2, Math.PI, XYZ.BasisZ);
				xyz3 = Geometry.RotateTo(xyz3, Math.PI, XYZ.BasisZ);
				double num = 0.0;
				double num2 = 0.0;
				this.GetFamilyWidthAndLength(fIns, out num2, out num);
				XYZ xyz4 = xyz3 * num2;
				xyz4 = Geometry.RotateTo(xyz4, dAngle, XYZ.BasisZ);
				xyz += xyz4;
				xyz3 = Geometry.RotateTo(xyz3, Math.PI, XYZ.BasisZ);
			}
			xyz2 *= dLength;
			xyz3 *= dHori;
			XYZ xyz5 = xyz2 + xyz3;
			xyz5 = Geometry.RotateTo(xyz5, dAngle, XYZ.BasisZ);
			return xyz + xyz5 / 2.0;
		}

		private XYZ GetTopPitPtInsert(FamilyInstance fIns, double dLength, double dHori, double dAngle, bool bIsTurn)
		{
			XYZ xyz = this.GetInstanceInsertPoint(fIns);
			XYZ xyz2 = -XYZ.BasisY;
			XYZ xyz3 = XYZ.BasisX;
			double num = 0.0;
			double num2 = 0.0;
			this.GetFamilyWidthAndLength(fIns, out num2, out num);
			if (bIsTurn)
			{
				xyz2 = Geometry.RotateTo(xyz2, Math.PI, XYZ.BasisZ);
				xyz3 = Geometry.RotateTo(xyz3, Math.PI, XYZ.BasisZ);
				XYZ xyz4 = xyz3 * num2;
				xyz4 = Geometry.RotateTo(xyz4, dAngle, XYZ.BasisZ);
				xyz += xyz4;
				xyz3 = Geometry.RotateTo(xyz3, Math.PI, XYZ.BasisZ);
			}
			XYZ xyz5 = -xyz2 * num;
			xyz2 *= dLength;
			xyz3 *= dHori;
			XYZ xyz6 = xyz2 + xyz3;
			xyz6 = Geometry.RotateTo(xyz6, dAngle, XYZ.BasisZ);
			xyz5 = Geometry.RotateTo(xyz5, dAngle, XYZ.BasisZ);
			return xyz + xyz6 / 2.0 + xyz5;
		}

		private void SetInstanceStringParamValue(FamilyInstance famIns, string sParamName, string sValue)
		{
			Parameter parameter = famIns.GetParameter(sParamName);
			if (parameter != null && !parameter.IsReadOnly && parameter.AsString() != sValue)
			{
				parameter.Set(sValue);
			}
		}

		private void SetInstanceDoubleParamValue(FamilyInstance famIns, string sParamName, double dValue)
		{
			Parameter parameter = famIns.GetParameter(sParamName);
			if (parameter != null && !parameter.IsReadOnly && parameter.AsDouble() != dValue)
			{
				parameter.Set(dValue);
			}
		}

		private void SetInstanceDoubleParamValue(FamilyInstance famIns, double dValu)
		{
			famIns.get_Parameter(BuiltInParameter.INSTANCE_FREE_HOST_OFFSET_PARAM).Set(dValu);
		}

		private void SetInstanceIntParam(FamilyInstance famIns, string sParamName, bool bVisible)
		{
			Parameter parameter = famIns.GetParameter(sParamName);
			if (parameter != null && !parameter.IsReadOnly)
			{
				int num = parameter.AsInteger();
				if (bVisible)
				{
					if (num == 0)
					{
						parameter.Set(1);
						return;
					}
				}
				else if (1 == num)
				{
					parameter.Set(0);
				}
			}
		}

		private void SetZeroFloorType(FamilyInstance famIns, Autodesk.Revit.DB.Document doc, bool bUpStairs, bool bTurn, int nRunCount)
		{
			Transaction transaction = new Transaction(this.m_Document, "set visible");
			transaction.Start();
			try
			{
				if (bTurn)
				{
					this.SetInstanceIntParam(famIns, "图例箭头下", bUpStairs);
					this.SetInstanceIntParam(famIns, "图例箭头上", !bUpStairs);
				}
				else
				{
					this.SetInstanceIntParam(famIns, "图例箭头下", !bUpStairs);
					this.SetInstanceIntParam(famIns, "图例箭头上", bUpStairs);
				}
				this.SetInstanceIntParam(famIns, "图例注释文字可见性", true);
				this.SetInstanceIntParam(famIns, "底部注释文字可见性", true);
				this.SetInstanceStringParamValue(famIns, "底部注释文字", "上");
				this.SetInstanceStringParamValue(famIns, "顶部注释文字", "下");
				if (bTurn)
				{
					double dValue = Math.PI;
					this.SetInstanceDoubleParamValue(famIns, "文字角度(上)", dValue);
					this.SetInstanceDoubleParamValue(famIns, "文字角度(下)", dValue);
				}
				transaction.Commit();
			}
			catch (Exception)
			{
				transaction.RollBack();
			}
		}

		private void SetFirstFloorType(FamilyInstance famIns, Autodesk.Revit.DB.Document doc, bool bUpStairs, bool bTurn, int nRunCount)
		{
			Transaction transaction = new Transaction(this.m_Document, "set visible");
			transaction.Start();
			try
			{
				if (1 == nRunCount)
				{
					this.SetInstanceIntParam(famIns, "首层箭头上", true);
					this.SetInstanceIntParam(famIns, "首层箭头下", false);
				}
				else
				{
					this.SetInstanceIntParam(famIns, "首层箭头上", bUpStairs);
					this.SetInstanceIntParam(famIns, "首层箭头下", !bUpStairs);
				}
				this.SetInstanceIntParam(famIns, "首层线可见性", true);
				this.SetInstanceIntParam(famIns, "顶部注释文字可见性", false);
				this.SetInstanceIntParam(famIns, "图例注释文字可见性", false);
				this.SetInstanceIntParam(famIns, "顶层箭头下", false);
				this.SetInstanceIntParam(famIns, "顶层箭头上", false);
				this.SetInstanceIntParam(famIns, "底部注释文字可见性", true);
				this.SetInstanceIntParam(famIns, "中层箭头下下", false);
				this.SetInstanceIntParam(famIns, "中层箭头下上", false);
				this.SetInstanceIntParam(famIns, "中层箭头上下", false);
				this.SetInstanceIntParam(famIns, "中层箭头上上", false);
				if (!bUpStairs && nRunCount > 1)
				{
					this.SetInstanceStringParamValue(famIns, "底部注释文字", "下");
				}
				if (bTurn)
				{
					double dValue = Math.PI;
					this.SetInstanceDoubleParamValue(famIns, "文字角度(上)", dValue);
					this.SetInstanceDoubleParamValue(famIns, "文字角度(下)", dValue);
				}
				transaction.Commit();
			}
			catch (Exception)
			{
				transaction.RollBack();
			}
		}

		private void SetTopFloorType(FamilyInstance famIns, Autodesk.Revit.DB.Document doc, bool bUpStairs, bool bTurn, int nRunCount)
		{
			Transaction transaction = new Transaction(this.m_Document, "set visible");
			transaction.Start();
			try
			{
				this.SetInstanceIntParam(famIns, "首层箭头上", false);
				this.SetInstanceIntParam(famIns, "首层箭头下", false);
				this.SetInstanceIntParam(famIns, "顶部注释文字可见性", true);
				this.SetInstanceIntParam(famIns, "顶层线可见性", true);
				if (1 == nRunCount)
				{
					this.SetInstanceIntParam(famIns, "顶层箭头下", true);
					this.SetInstanceIntParam(famIns, "顶层箭头上", false);
				}
				else
				{
					this.SetInstanceIntParam(famIns, "顶层箭头下", bUpStairs);
					this.SetInstanceIntParam(famIns, "顶层箭头上", !bUpStairs);
				}
				this.SetInstanceIntParam(famIns, "底部注释文字可见性", false);
				this.SetInstanceIntParam(famIns, "中层箭头下下", false);
				this.SetInstanceIntParam(famIns, "中层箭头下上", false);
				this.SetInstanceIntParam(famIns, "中层箭头上下", false);
				this.SetInstanceIntParam(famIns, "中层箭头上上", false);
				if (!bUpStairs)
				{
					this.SetInstanceStringParamValue(famIns, "顶部注释文字", "上");
				}
				if (bTurn)
				{
					double dValue = Math.PI;
					this.SetInstanceDoubleParamValue(famIns, "文字角度(上)", dValue);
					this.SetInstanceDoubleParamValue(famIns, "文字角度(下)", dValue);
				}
				transaction.Commit();
			}
			catch (Exception)
			{
				transaction.RollBack();
			}
		}

		private void SetMidFloorType(FamilyInstance famIns, Autodesk.Revit.DB.Document doc, bool bUpStairs, bool bTurn, Escalator.PlaceType pType, int nRunCount)
		{
			Transaction transaction = new Transaction(this.m_Document, "set visible");
			transaction.Start();
			try
			{
				this.SetInstanceIntParam(famIns, "首层箭头上", false);
				this.SetInstanceIntParam(famIns, "首层箭头下", false);
				this.SetInstanceIntParam(famIns, "顶部注释文字可见性", true);
				this.SetInstanceIntParam(famIns, "顶层箭头下", false);
				this.SetInstanceIntParam(famIns, "顶层箭头上", false);
				this.SetInstanceIntParam(famIns, "底部注释文字可见性", true);
				this.SetInstanceIntParam(famIns, "中层下部线可见性", true);
				this.SetInstanceIntParam(famIns, "中层上部线可见性", true);
				if (1 == nRunCount)
				{
					this.SetInstanceIntParam(famIns, "中层箭头下下", false);
					this.SetInstanceIntParam(famIns, "中层箭头下上", true);
					this.SetInstanceIntParam(famIns, "中层箭头上下", true);
					this.SetInstanceIntParam(famIns, "中层箭头上上", false);
				}
				else
				{
					bool bVisible = false;
					bool bVisible2 = false;
					bool bVisible3 = false;
					bool bVisible4 = false;
					string sValue = "下";
					string sValue2 = "上";
					if (bUpStairs)
					{
						switch (pType)
						{
						case Escalator.PlaceType.PT_ParallelSameDirect:
						case Escalator.PlaceType.PT_CrossingSameDirect:
							sValue = "上";
							bVisible2 = true;
							bVisible4 = true;
							break;
						case Escalator.PlaceType.PT_ParallelReverseDirect:
						case Escalator.PlaceType.PT_CrossingReverseDirect:
							bVisible2 = true;
							bVisible3 = true;
							break;
						}
					}
					else
					{
						switch (pType)
						{
						case Escalator.PlaceType.PT_ParallelSameDirect:
							sValue2 = "下";
							bVisible = true;
							bVisible3 = true;
							break;
						case Escalator.PlaceType.PT_ParallelReverseDirect:
							sValue = "上";
							sValue2 = "下";
							bVisible = true;
							bVisible4 = true;
							break;
						case Escalator.PlaceType.PT_CrossingSameDirect:
							sValue = "下";
							sValue2 = "下";
							if (bTurn)
							{
								bVisible = true;
								bVisible3 = true;
							}
							else
							{
								bVisible2 = true;
								bVisible4 = true;
							}
							break;
						case Escalator.PlaceType.PT_CrossingReverseDirect:
							sValue = "上";
							sValue2 = "下";
							bVisible = true;
							bVisible4 = true;
							break;
						}
					}
					this.SetInstanceIntParam(famIns, "中层箭头下下", bVisible);
					this.SetInstanceIntParam(famIns, "中层箭头下上", bVisible2);
					this.SetInstanceIntParam(famIns, "中层箭头上下", bVisible3);
					this.SetInstanceIntParam(famIns, "中层箭头上上", bVisible4);
					this.SetInstanceStringParamValue(famIns, "顶部注释文字", sValue);
					this.SetInstanceStringParamValue(famIns, "底部注释文字", sValue2);
				}
				if (bTurn)
				{
					double dValue = Math.PI;
					this.SetInstanceDoubleParamValue(famIns, "文字角度(上)", dValue);
					this.SetInstanceDoubleParamValue(famIns, "文字角度(下)", dValue);
				}
				transaction.Commit();
			}
			catch (Exception)
			{
				transaction.RollBack();
			}
		}

        private void DealInstanceDirection(List<FamilyInstance> arFamIns, List<Escalator.Direction> arDirecion, List<Escalator.Direction> arTurn, YJKRevitStairs.StairsModel.DataInfos.FloorType fType, Escalator.PlaceType pType, double dAngle, string sFamName)
		{
			if (arFamIns.Count == arDirecion.Count)
			{
				int count = arFamIns.Count;
				bool flag = Common.IsDoubleEquals(Math.PI, dAngle, 1E-15);
				foreach (Escalator.Direction direction in arDirecion)
				{
					int nRunIndex = direction.m_nRunIndex;
					bool flag2 = arTurn[nRunIndex].m_bIsReverse;
					if (flag)
					{
						flag2 = !flag2;
					}
					bool bUpStairs = !direction.m_bIsReverse;
					FamilyInstance famIns = arFamIns[nRunIndex];
					switch (fType)
					{
                    case YJKRevitStairs.StairsModel.DataInfos.FloorType.FT_Bottom:
						this.SetFirstFloorType(famIns, this.m_Document, bUpStairs, flag2, count);
						break;
                    case YJKRevitStairs.StairsModel.DataInfos.FloorType.FT_Mid:
						this.SetMidFloorType(famIns, this.m_Document, bUpStairs, flag2, pType, count);
						break;
                    case YJKRevitStairs.StairsModel.DataInfos.FloorType.FT_Top:
						this.SetTopFloorType(famIns, this.m_Document, bUpStairs, flag2, count);
						break;
					}
					if (sFamName.Equals("自动人行道(0)"))
					{
						this.SetZeroFloorType(famIns, this.m_Document, bUpStairs, flag2, count);
					}
				}
			}
		}

		public bool CreateEscalator(Escalator param_stairs)
		{
			bool result = true;
			string str = FormParamManager.GetStairsFamiliyPath(param_stairs.m_sRvtVersion) + "Escalator\\";
			string text = "自动扶梯梯坑";
			string sFamilyName = param_stairs.m_sFamilyName;
			string str2 = ".rfa";
			string sFamFullPath = str + sFamilyName + str2;
			string sSymbolName = param_stairs.m_sSymbolName;
			string sPitFamPath = str + text + str2;
			string sPitSymbolName = text;
			int nRunCount = param_stairs.m_nRunCount;
			Escalator.PosInsertType posInsertType = param_stairs.m_PosInsertType;
			double dRotateAngle = param_stairs.m_dRotateAngle;
			double dStairsDis = param_stairs.m_dStairsDis;
			XYZ ptInsert = param_stairs.m_ptInsert;
			bool bNoteUpStairs = param_stairs.m_bNoteUpStairs;
			FamilyInstance familyInstance = this.CreateOneInstance(this.m_Document, sFamFullPath, sSymbolName, param_stairs, ptInsert);
			if (familyInstance != null && familyInstance.IsValidObject)
			{
				XYZ copyInstanceTransVector = this.GetCopyInstanceTransVector(posInsertType, familyInstance, dStairsDis, dRotateAngle);
				List<FamilyInstance> list = this.CopyEsclatorByVector(familyInstance, copyInstanceTransVector, nRunCount - 1);
				if (posInsertType == Escalator.PosInsertType.PIT_RhtTop || posInsertType == Escalator.PosInsertType.PIT_RhtBtm)
				{
					list.Reverse();
				}
				List<Escalator.Direction> list2 = new List<Escalator.Direction>();
				this.DealEscalatorTurn(param_stairs, list, ref list2);
				if (bNoteUpStairs)
				{
					this.DealInstanceDirection(list, param_stairs.m_arDirection, list2, param_stairs.m_FloorType, param_stairs.m_PlaceType, dRotateAngle, sFamilyName);
				}
				this.CreateEscalatorPit(param_stairs, list, list2, sPitFamPath, sPitSymbolName);
				this.SetEscalatorNumber(param_stairs, list);
			}
			else
			{
				result = false;
			}
			return result;
		}

		private double GetTreadThinckness(FamilyInstance famIns)
		{
			double result = 0.0;
			if (famIns != null)
			{
				Parameter parameter = famIns.GetParameter("踏板厚度");
				if (parameter != null)
				{
					result = parameter.AsDouble();
				}
			}
			return result;
		}

		private void CreateEscalatorPit(Escalator param_stairs, List<FamilyInstance> allFamIns, List<Escalator.Direction> listTurnData, string sPitFamPath, string sPitSymbolName)
		{
			double dBtmPitLength = param_stairs.m_dBtmPitLength;
			double dTopPitLength = param_stairs.m_dTopPitLength;
			double dBtmPitDepth = param_stairs.m_dBtmPitDepth;
			double dTopPitDepth = param_stairs.m_dTopPitDepth;
			double num = param_stairs.m_dBtmPitExturn * 2.0;
			double num2 = param_stairs.m_dTopPitExturn * 2.0;
			double dStairsHigh = param_stairs.m_dStairsHigh;
			double dStairsOffset = param_stairs.m_dStairsOffset;
			double num3 = 0.0;
			if (param_stairs.m_sFamilyName.Equals("自动人行道(0)"))
			{
				num3 = this.GetTreadThinckness(allFamIns.First<FamilyInstance>());
			}
			double dOffset = dStairsOffset + num3;
			double dOffset2 = dStairsOffset + dStairsHigh + num3;
			double dRotateAngle = param_stairs.m_dRotateAngle;
			double dStairsDis = param_stairs.m_dStairsDis;
			foreach (Escalator.DrawPitData drawPitData in this.GetDrawPitData(listTurnData))
			{
				int nSpace = drawPitData.m_nSpace;
				int nRunIndex = drawPitData.m_Direction.m_nRunIndex;
				bool bIsReverse = drawPitData.m_Direction.m_bIsReverse;
				FamilyInstance familyInstance = allFamIns[nRunIndex];
				double num4 = 0.0;
				double num5 = 0.0;
				this.GetFamilyWidthAndLength(familyInstance, out num5, out num4);
				num5 = num5 * (double)(nSpace + 1) + dStairsDis * (double)nSpace;
				double dWidth = num5 + num;
				double dWidth2 = num5 + num2;
				XYZ btmPitPtInsert = this.GetBtmPitPtInsert(familyInstance, dBtmPitLength, num5, dRotateAngle, bIsReverse);
				this.CreateOnePitAtPoint(this.m_Document, sPitFamPath, sPitSymbolName, dBtmPitLength, dWidth, dBtmPitDepth, btmPitPtInsert, dRotateAngle, dOffset);
				XYZ topPitPtInsert = this.GetTopPitPtInsert(familyInstance, dTopPitLength, num5, dRotateAngle, bIsReverse);
				this.CreateOnePitAtPoint(this.m_Document, sPitFamPath, sPitSymbolName, dTopPitLength, dWidth2, dTopPitDepth, topPitPtInsert, dRotateAngle, dOffset2);
			}
		}

		private void DealEscalatorTurn(Escalator param_stairs, List<FamilyInstance> allFamIns, ref List<Escalator.Direction> listTurnData)
		{
			int nRunCount = param_stairs.m_nRunCount;
			bool bLftRhtTurn = param_stairs.m_bLftRhtTurn;
			bool bUpDownTurn = param_stairs.m_bUpDownTurn;
			UpStairsType upStairsType = param_stairs.m_UpStairsType;
			Escalator.PlaceType placeType = param_stairs.m_PlaceType;
			Escalator.PosInsertType posInsertType = param_stairs.m_PosInsertType;
			double dRotateAngle = param_stairs.m_dRotateAngle;
			switch (nRunCount)
			{
			case 1:
			{
				if (bUpDownTurn)
				{
					this.TurnInstance(allFamIns[0], dRotateAngle);
					Escalator.Direction item = new Escalator.Direction(0, true);
					listTurnData.Add(item);
					return;
				}
				Escalator.Direction item2 = new Escalator.Direction(0, false);
				listTurnData.Add(item2);
				return;
			}
			case 2:
			{
				if (EscalatorTurnManger.IsLeftRunNeedTurn3D(nRunCount, upStairsType, placeType, bLftRhtTurn, bUpDownTurn))
				{
					this.TurnInstance(allFamIns[0], dRotateAngle);
					Escalator.Direction item3 = new Escalator.Direction(0, true);
					listTurnData.Add(item3);
				}
				else
				{
					Escalator.Direction item4 = new Escalator.Direction(0, false);
					listTurnData.Add(item4);
				}
				if (EscalatorTurnManger.IsMidOneRunNeedTurn3D(nRunCount, upStairsType, placeType, bLftRhtTurn, bUpDownTurn))
				{
					this.TurnInstance(allFamIns[1], dRotateAngle);
					Escalator.Direction item5 = new Escalator.Direction(1, true);
					listTurnData.Add(item5);
					return;
				}
				Escalator.Direction item6 = new Escalator.Direction(1, false);
				listTurnData.Add(item6);
				return;
			}
			case 3:
			{
				if (EscalatorTurnManger.IsLeftRunNeedTurn3D(nRunCount, upStairsType, placeType, bLftRhtTurn, bUpDownTurn))
				{
					this.TurnInstance(allFamIns[0], dRotateAngle);
					Escalator.Direction item7 = new Escalator.Direction(0, true);
					listTurnData.Add(item7);
				}
				else
				{
					Escalator.Direction item8 = new Escalator.Direction(0, false);
					listTurnData.Add(item8);
				}
				if (EscalatorTurnManger.IsMidOneRunNeedTurn3D(nRunCount, upStairsType, placeType, bLftRhtTurn, bUpDownTurn))
				{
					this.TurnInstance(allFamIns[1], dRotateAngle);
					Escalator.Direction item9 = new Escalator.Direction(1, true);
					listTurnData.Add(item9);
				}
				else
				{
					Escalator.Direction item10 = new Escalator.Direction(1, false);
					listTurnData.Add(item10);
				}
				if (EscalatorTurnManger.IsMidTwoRunNeedTurn3D(nRunCount, upStairsType, placeType, bLftRhtTurn, bUpDownTurn))
				{
					this.TurnInstance(allFamIns[2], dRotateAngle);
					Escalator.Direction item11 = new Escalator.Direction(2, true);
					listTurnData.Add(item11);
					return;
				}
				Escalator.Direction item12 = new Escalator.Direction(2, false);
				listTurnData.Add(item12);
				return;
			}
			case 4:
			{
				if (EscalatorTurnManger.IsLeftRunNeedTurn3D(nRunCount, upStairsType, placeType, bLftRhtTurn, bUpDownTurn))
				{
					this.TurnInstance(allFamIns[0], dRotateAngle);
					Escalator.Direction item13 = new Escalator.Direction(0, true);
					listTurnData.Add(item13);
				}
				else
				{
					Escalator.Direction item14 = new Escalator.Direction(0, false);
					listTurnData.Add(item14);
				}
				if (EscalatorTurnManger.IsMidOneRunNeedTurn3D(nRunCount, upStairsType, placeType, bLftRhtTurn, bUpDownTurn))
				{
					this.TurnInstance(allFamIns[1], dRotateAngle);
					Escalator.Direction item15 = new Escalator.Direction(1, true);
					listTurnData.Add(item15);
				}
				else
				{
					Escalator.Direction item16 = new Escalator.Direction(1, false);
					listTurnData.Add(item16);
				}
				if (EscalatorTurnManger.IsMidTwoRunNeedTurn3D(nRunCount, upStairsType, placeType, bLftRhtTurn, bUpDownTurn))
				{
					this.TurnInstance(allFamIns[2], dRotateAngle);
					Escalator.Direction item17 = new Escalator.Direction(2, true);
					listTurnData.Add(item17);
				}
				else
				{
					Escalator.Direction item18 = new Escalator.Direction(2, false);
					listTurnData.Add(item18);
				}
				if (EscalatorTurnManger.IsRightRunNeedTurn3D(nRunCount, upStairsType, placeType, bLftRhtTurn, bUpDownTurn))
				{
					this.TurnInstance(allFamIns[3], dRotateAngle);
					Escalator.Direction item19 = new Escalator.Direction(3, true);
					listTurnData.Add(item19);
					return;
				}
				Escalator.Direction item20 = new Escalator.Direction(3, false);
				listTurnData.Add(item20);
				return;
			}
			default:
				return;
			}
		}

		private string CreateEscalatorNumber(string sPreFix, int nSerial, string sSubFix)
		{
			return sPreFix + nSerial.ToString() + sSubFix;
		}

		private void SetEscalatorNumber(Escalator param_stairs, List<FamilyInstance> allFamIns)
		{
			string sNumPreFix = param_stairs.m_sNumPreFix;
			int nNumSerial = param_stairs.m_nNumSerial;
			string sNumSubFix = param_stairs.m_sNumSubFix;
			Transaction transaction = new Transaction(this.m_Document, "setnumber");
			transaction.Start();
			try
			{
				int count = allFamIns.Count;
				for (int i = 0; i < count; i++)
				{
					FamilyInstance familyInstance = allFamIns[i];
					if (familyInstance != null && familyInstance.IsValidObject)
					{
						string text = this.CreateEscalatorNumber(sNumPreFix, nNumSerial + i, sNumSubFix);
						if (!string.IsNullOrEmpty(text))
						{
							this.SetInstanceStringParamValue(familyInstance, "扶梯编号", text);
							this.SetInstanceStringParamValue(familyInstance, "人行道编号", text);
						}
					}
				}
				transaction.Commit();
			}
			catch (Exception)
			{
				transaction.RollBack();
			}
		}
	}
}
